package hexagon.security.core.domain;

import lombok.*;

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.List;

/**
 * @author XueguiYuan
 * @version 1.0 (created time: 2016/12/3).
 */
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString(of = {"user", "authority", "scope"})
@Entity
@Table(name = "authorization")
public class Authorization extends SecurityAbstractEntity {

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "authority_id")
    private Authority authority;

    @ManyToOne
    @JoinColumn(name = "scope_id")
    private Scope scope;

    public static final Finder<Long, Authorization> find = new Finder<>(Authorization.class);

    @Override
    public String[] businessKeys() {
        return new String[]{"user", "authority"};
    }

    public static List<Authorization> findByUser(User user) {
        return find.where()
                .eq("user", user)
                .findList();
    }

    public static boolean exists(User user, Authority authority) {
        return find.where()
                .eq("user", user)
                .eq("authority", authority)
                .findCount() > 0;
    }

    public static Authorization findByUserInAuthority(User user, Authority authority) {
        return find.where()
                .eq("user", user)
                .eq("authority", authority)
                .setMaxRows(1)
                .findUnique();
    }

    public void changeScope(Scope scope) {
        this.setScope(scope);
        this.save();
    }

    public static Authorization findByUserOfAuthorityInScope(User user, Authority authority, Scope scope) {
        return find.where()
                .eq("user", user)
                .eq("authority", authority)
                .eq("scope", scope)
                .setMaxRows(1)
                .findUnique();
    }

    public static List<Authority> findAuthoritiesByUserInScope(User user, Scope scope) {
        return Authority.find.where()
                .eq("authorizations.user", user)
                .eq("authorizations.scope", scope)
                .findList();
    }
}
